import os
import json
from typing import Union
from public.path import get_project_path

path = get_project_path() + os.sep + "config" + os.sep + "config.ini"


class Configs(object):
    _instance = None

    def __new__(cls, *args, **kwargs):
        if not cls._instance:
            cls._instance = super().__new__(cls, *args, **kwargs)
        return cls._instance

    def __init__(self):
        self.DEVELOP: Union[bool, None] = None
        self.LOG_LEVEl: Union[str, None] = None
        self.SERVER_PORT: Union[int, None] = None
        self.GEVENT_MODE: Union[bool, None] = None
        self.THREADS: Union[int, None] = None

        self.REDIS_DB: Union[int, None] = None
        self.REDIS_PORT: Union[int, None] = None
        self.REDIS_HOST: Union[str, None] = None
        self.REDIS_MAX_CONNECTIONS: Union[int, None] = None
        self.REDIS_DECODE_RESPONSES: Union[bool, None] = None
        self.REDIS_PASSWD: Union[str, None] = None

        self.PG_USER: Union[str, None] = None
        self.PG_PASSWORD: Union[str, None] = None
        self.PG_HOST: Union[str, None] = None
        self.PG_PORT: Union[int, None] = None
        self.PG_DB_NAME: Union[str, None] = None

        self.initialization()

    def initialization(self):
        parm: dict = {
            "DEVELOP": "Bool",
            "LOG_LEVEl": "String",
            "SERVER_PORT": "Int",
            "GEVENT_MODE": "Bool",
            "THREADS": "Int",

            "REDIS_DB": "Int",
            "REDIS_PORT": "Int",
            "REDIS_HOST": "String",
            "REDIS_MAX_CONNECTIONS": "Int",
            "REDIS_DECODE_RESPONSES": "Bool",
            "REDIS_PASSWD": "String",

            "PG_USER": "String",
            "PG_PASSWORD": "String",
            "PG_HOST": "String",
            "PG_PORT": "Int",
            "PG_DB_NAME": "String"
        }
        if not os.path.exists(path):
            raise FileNotFoundError("FileNotFoundError")
        with open(path, "r") as file:
            data = file.readlines()
        parm_keys: list = list(parm.keys())
        for itr0 in parm_keys:
            for index1, itr1 in enumerate(data):
                line: list = itr1.strip().split()
                if not itr1.startswith("#") and len(line) == 3 and line[0] == itr0:
                    line: list = itr1.strip().split()
                    types: str = parm.get(itr0)
                    if types == "Bool":
                        if line[2] == "True":
                            self.__setattr__(line[0], True)
                        elif line[2] == "False":
                            self.__setattr__(line[0], False)
                        else:
                            raise ValueError
                    if types == "Int":
                        self.__setattr__(line[0], int(line[2]))
                    if types == "String":
                        self.__setattr__(line[0], str(line[2]))
                    break

    def __repr__(self):
        return json.dumps({
            "DEVELOP": self.DEVELOP,
            "LOG_LEVEl": self.LOG_LEVEl,
            "SERVER_PORT": self.SERVER_PORT,
            "GEVENT_MODE": self.GEVENT_MODE,
            "THREADS": self.THREADS,

            "REDIS_DB": self.REDIS_DB,
            "REDIS_PORT": self.REDIS_PORT,
            "REDIS_HOST": self.REDIS_HOST,
            "REDIS_MAX_CONNECTIONS": self.REDIS_MAX_CONNECTIONS,
            "REDIS_DECODE_RESPONSES": self.REDIS_DECODE_RESPONSES,
            "REDIS_PASSWD": self.REDIS_PASSWD,

            "PG_USER": self.PG_USER,
            "PG_PASSWORD": self.PG_PASSWORD,
            "PG_HOST": self.PG_HOST,
            "PG_PORT": self.PG_PORT,
            "PG_DB_NAME": self.PG_DB_NAME
        })


config: Configs = Configs()
